package edu.je.prs.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.junqson.je.common.constant.AppRedisKey;
import com.junqson.je.common.model.ApiResult;
import edu.je.prs.Mapper.AnalyseDataMapper;
import edu.je.prs.Mapper.ResumeInfoMapper;
import edu.je.prs.Model.AnalyseData;
import edu.je.prs.Model.ResumeInfo;
import edu.je.prs.util.PearsonUtil;
import edu.je.prs.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import springfox.documentation.spring.web.json.Json;

import java.util.*;

/**
 * @Description:
 * @author: Anhlaidh
 * @date: 2021-04-22 20:58
 */
@Service
public class AnalyzeService {
    @Autowired
    StringRedisTemplate redisTemplate;
    @Autowired
    AnalyseDataMapper analyseDataMapper;
    @Autowired
    ResumeInfoMapper resumeInfoMapper;

    //a b  - >c
    public ApiResult analyzeExperience() {
        List<AnalyseData> list = analyseDataMapper.queryAll();
        HashMap<ExperienceVo, List<String>> map = new HashMap<>();
        for (int i = 0; i < list.size(); i++) {
            AnalyseData analyseData = list.get(i);
            ExperienceVo cur = new ExperienceVo();
            cur.setLabel(analyseData.getExperience());
            cur.setType((analyseData.getEducation()));
            if (!map.containsKey(cur)) {
                ArrayList<String> value = new ArrayList<>();
                value.add(analyseData.getSalary());
                map.put(cur, value);
            } else {
                List<String> salaryStr = map.get(cur);
                salaryStr.add(analyseData.getSalary());
            }
        }
        Iterator<ExperienceVo> iterator = map.keySet().iterator();
        List<ExperienceVo> result = new ArrayList<>();
        while (iterator.hasNext()) {
            ExperienceVo cur = iterator.next();
            List<String> salaryStr = map.get(cur);
            int count = 0;

            for (int i = 0; i < salaryStr.size(); i++) {
                count += getSalaryValue(salaryStr.get(i));
            }
            count /= salaryStr.size();
            cur.setValue(count);
            result.add(cur);

        }
        Collections.sort(result, new Comparator<ExperienceVo>() {
            @Override
            public int compare(ExperienceVo o1, ExperienceVo o2) {
                return o2.getValue() - o1.getValue();
            }
        });
        return ApiResult.success(result);

    }

    private int getSalaryValue(String s) {
        int count = 0;
        if (s.contains("万")) {
            String substring = s.substring(s.indexOf("-") + 1, s.lastIndexOf("万"));
            count = (int) (Float.parseFloat(substring) * 10000);
        } else if (s.contains("千")) {
            String substring = s.substring(s.indexOf("-") + 1, s.lastIndexOf("千"));
            count = (int) Float.parseFloat(substring) * 1000;
        }
        if (s.contains("年")) {
            count /= 12;

        }
        return count;
    }

    public ApiResult analyzeCorrelation() {
        List<AnalyseData> list = analyseDataMapper.queryAll();
        List<Double> exp = new ArrayList<>();
        List<Double> salary = new ArrayList<>();
        CorrelationVo result = new CorrelationVo();
        for (int i = 0; i < list.size(); i++) {
            AnalyseData analyseData = list.get(i);
            if (!"异地招聘".equals(analyseData.getPosition())) {
                continue;
            } else {
                double salaryValue = getSalaryValue(analyseData.getSalary());
                double expValue = getExpValue(analyseData.getExperience());
                exp.add(expValue);
                salary.add(salaryValue);
                result.getData().add(new CorrelationVo.Point((int) expValue, (int) salaryValue));
            }
        }
        double pearsonCorrelationScore = PearsonUtil.getPearsonCorrelationScore(salary, exp);
        result.setScore(pearsonCorrelationScore);
        return ApiResult.success(JSONObject.toJSON(result));
    }

    private int getExpValue(String experience) {
        if ("在校生/应届生".equals(experience)) {
            return 0;
        } else {
            return experience.charAt(0) - '0';
        }
    }

    public ApiResult analyzeFrozen(int id) {
        String s = redisTemplate.opsForValue().get(AppRedisKey.FROZEN_SET);
        List<FrozenSetVo> frozenSetVos = JSON.parseArray(s, FrozenSetVo.class);
        ResumeInfo resumeInfo = resumeInfoMapper.selectByPrimaryKey(id);
        String[] skills = resumeInfo.getSkills().split(",");
        List<AnalyzedFrozenVo> result = getFrozen(skills, frozenSetVos);
        return ApiResult.success(result);

    }

    public List<AnalyzedFrozenVo> getFrozen(String[] skills, List<FrozenSetVo> frozenSetVos) {
        List<AnalyzedFrozenVo> result = new ArrayList<>();
        for (int i = 0; i < skills.length; i++) {
            String skill = skills[i];
            for (int j = 0; j < frozenSetVos.size(); j++) {
                FrozenSetVo cur = frozenSetVos.get(j);
                if (cur.getSource().length > 1) {
                    continue;
                }
                if (cur.getTarget().length > 1) {
                    continue;
                }
                if (skill.equalsIgnoreCase(cur.getSource()[0])) {
                    AnalyzedFrozenVo analyzedFrozenVo = new AnalyzedFrozenVo();
                    analyzedFrozenVo.setSource(skill.toLowerCase());
                    analyzedFrozenVo.setTarget(cur.getTarget()[0].toLowerCase());
                    analyzedFrozenVo.setValue(cur.getValue());
                    result.add(analyzedFrozenVo);
                }
            }
        }
        return result;
    }

    public ApiResult analyzePopularity(int id) {
        String s = redisTemplate.opsForValue().get(AppRedisKey.POPULARITY);
        ResumeInfo resumeInfo = resumeInfoMapper.selectByPrimaryKey(id);
        String[] skills = resumeInfo.getSkills().split(",");
        List<PopularityVo> popularityVos = JSON.parseArray(s, PopularityVo.class);
        List<AnalyzedPopularityVo> result = getPopularity(skills, popularityVos);
        return ApiResult.success(result);
    }

    private List<AnalyzedPopularityVo> getPopularity(String[] skills, List<PopularityVo> popularityVos) {
        List<AnalyzedPopularityVo> result = new ArrayList<>();
        for (int i = 0; i < skills.length; i++) {
            for (int j = 0; j < popularityVos.size(); j++) {
                PopularityVo popularityVo = popularityVos.get(j);
                if (popularityVo.getName().length > 1) {
                    continue;
                }
                if (skills[i].equalsIgnoreCase(popularityVo.getName()[0])) {
                    AnalyzedPopularityVo analyzedPopularityVo = new AnalyzedPopularityVo();
                    analyzedPopularityVo.setName(skills[i]);
                    analyzedPopularityVo.setValue(popularityVo.getValue());
                    if (!result.contains(analyzedPopularityVo)) {
                        result.add(analyzedPopularityVo);
                    }
                }
            }
        }
        return result;
    }


    public ApiResult multianalyzeFrozen(int id) {
        String s = redisTemplate.opsForValue().get(AppRedisKey.FROZEN_SET);
        List<FrozenSetVo> frozenSetVos = JSON.parseArray(s, FrozenSetVo.class);
        ResumeInfo resumeInfo = resumeInfoMapper.selectByPrimaryKey(id);
        String[] skills = resumeInfo.getSkills().split(",");
        //一对多
        HashSet<String> set = new HashSet<>();
        for (int i = 0; i < skills.length; i++) {
            String skill = skills[i];
            for (int j = 0; j < frozenSetVos.size(); j++) {
                FrozenSetVo cur = frozenSetVos.get(j);
                if (cur.getSource().length > 1) {
                    continue;
                }
                String[] targets = cur.getTarget();

                for (int k = 0; k < targets.length; k++) {
                    if (skill.equalsIgnoreCase(cur.getSource()[0])) {
                        set.add(cur.getTarget()[k]);
                    }
                }

            }
        }
        //set : targets
        String[] temp = new String[set.size()];
        String[] targets = set.toArray(temp);
        String popS = redisTemplate.opsForValue().get(AppRedisKey.POPULARITY);
        List<PopularityVo> popularityVos = JSON.parseArray(popS, PopularityVo.class);

        List<AnalyzedPopularityVo> result = getPopularity(targets, popularityVos);

        return ApiResult.success(result);
    }
}
